﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Syspetro.Core;
using Syspetro.Core.ErrorException;
using Syspetro.Core.Localization;
using Syspetro.Core.Resources;
using Syspetro.Deploy.Managers;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Syspetro.Deploy.Middleware
{
    public class ErrorHandling
    {
        private readonly RequestDelegate next;
        private readonly ILoggerFactory factory;
        public ErrorHandling(RequestDelegate next, ILoggerFactory factory)
        {
            this.next = next;
            this.factory = factory;
        }
        public async Task InvokeAsync(HttpContext context)
        {
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(context, ex);
            }
        }
        private Task HandleExceptionAsync(HttpContext context, Exception ex)
        {
            var code = HttpStatusCode.BadRequest;
            string msg = SharedResource.UnknownError;
            string result;
            if (ex is IErrorException)
            {
                var error = ex as IErrorException;
                code = error.Code();
                msg = error.Message();
                if (error.IsDetails)
                    result = JsonConvert.SerializeObject(new { Message = $"{msg}:{ex.Message}", ex.StackTrace });
                else
                    result = JsonConvert.SerializeObject(new { Message = $"{msg}:{ex.Message}" });
            }
            else
            {
                result = JsonConvert.SerializeObject(new { Message = $"{msg}:{ex.Message}", ex.StackTrace });
            }
            var loger = factory.CreateLogger(context.Request.Path);
            loger.LogError(ex, ex.Message);

            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)code;
            return context.Response.WriteAsync(result);
        }
    }
}
